package com.it.App.config;

import com.it.App.filter.JwtFilter;
import com.it.App.realm.MyRealm;
import com.it.App.shiro.MyCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @DateTime: 2023/11/28/12:53
 * @注释: 配置Shiro的两个关键组件：Web安全管理器 (DefaultWebSecurityManager) 和 Shiro过滤器工厂 (ShiroFilterFactoryBean)
 **/
@Configuration
public class ShrioConfig {
    @Autowired
    private MyRealm myRealm;

    @Autowired
    private MyCredentialsMatcher myCredentialsMatcher;


    /**
     * 配置默认的Web安全管理器
     *
     * @return 默认的Web安全管理器
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager() {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        // 设置自定义的凭证匹配器
        myRealm.setCredentialsMatcher(myCredentialsMatcher);
        // 注入自定义的Realm
        manager.setRealm(myRealm);
        return manager;
    }
    /**
     * 配置Shiro过滤器工厂
     *
     * @param manager Web安全管理器
     * @param jwtFilter JWT过滤器
     * @return Shiro过滤器工厂
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager manager, JwtFilter jwtFilter) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 设置Web安全管理器
        shiroFilterFactoryBean.setSecurityManager(manager);

        // 设置JWT过滤器
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("jwt", jwtFilter);
        shiroFilterFactoryBean.setFilters(filterMap);

        // 设置URL权限配置
        Map<String, String> map = new LinkedHashMap<>();
        // 放行Swagger相关的URL
        map.put("/favicon.ico", "anon");

        map.put("/swagger-resources/**", "anon");
        map.put("/v2/api-docs", "anon");
        map.put("/swagger-ui.html", "anon");
        map.put("/webjars/**", "anon");
        map.put("/sys/login", "anon");
        map.put("/sys/logout", "anon");

        // 设置其他URL需要经过JWT过滤器
        map.put("/**", "jwt");

        // 设置登录URL和未授权URL
        shiroFilterFactoryBean.setLoginUrl("/user/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/user/login");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        return shiroFilterFactoryBean;
    }

    @Bean
    public JwtFilter getJwtFilter() {
        return new JwtFilter();
    }

    /**
     * 创建AuthorizationAttributeSourceAdvisor Bean，用于支持Shiro注解 (开启注解代理)
     *
     * @param securityManager 安全管理器
     * @return AuthorizationAttributeSourceAdvisor Bean
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        // 设置安全管理器
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    /**
     * 创建DefaultAdvisorAutoProxyCreator Bean，用于自动创建代理对象
     *
     * @return DefaultAdvisorAutoProxyCreator Bean
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        // 设置是否使用CGLIB代理，默认为false，即使用JDK动态代理
        creator.setProxyTargetClass(true);
        return creator;
    }

}
